package com.zxb.framework.security.filter;

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import com.zxb.common.core.domain.model.LoginUser;
import com.zxb.common.utils.SecurityUtils;
import com.zxb.common.utils.StringUtils;
import com.zxb.framework.web.service.TokenService;

/**
 * token过滤器 验证token有效性
 *
 * @author ruoyi
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
{
    @Autowired
    private TokenService tokenService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException
    {
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
        {
            tokenService.verifyToken(loginUser);
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }
        chain.doFilter(request, response);
    }
}

//
//作用：
//
//        这个类是一个 过滤器，它会在每次请求到达目标前执行，用于验证用户提供的 Token 是否有效。
//        具体功能：
//        从请求中获取登录用户信息：LoginUser loginUser = tokenService.getLoginUser(request); 会从请求的 Authorization 头中提取 Token，然后获取到用户信息。
//        验证 Token 的有效性：如果获取到的用户信息不为空，且当前没有其他的认证信息存在，调用 tokenService.verifyToken(loginUser) 来验证 Token 是否有效。
//        创建认证对象并存储：创建一个 UsernamePasswordAuthenticationToken 对象，把用户信息和权限信息保存到 Spring Security 的安全上下文中，表示用户已认证。
//        继续请求：调用 chain.doFilter(request, response);，将请求继续传递给下一个过滤器或者目标。
//        通俗解释： 当用户访问网站时，这个过滤器就像是门卫，会先查看用户提交的“通行证”（Token）。如果“通行证”有效，那么门卫会让用户继续往下走，并把用户的信息记录下来，供后面的流程使用。如果用户没有提交有效的“通行证”，门卫就不会记录用户身份信息。
